package com.lixinlei.security.api.controller;

import java.io.IOException;
import java.util.List;

import com.lixinlei.security.api.service.UserService;
import com.lixinlei.security.api.vo.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * request.getSession() 的逻辑：
     * 根据浏览器传来的 sessionId 在内存中找对应的 Session；
     * 如果有现成的 Session，就返回；
     * 如果没有现成的 Session，就创建一个新的返回；
     * @param user
     * @param request
     * @throws IOException
     */
    @GetMapping("/login")
    public void login(@Validated UserInfo user, HttpServletRequest request) throws IOException {
        UserInfo info = userService.login(user);
        // 试图获取老 Session
        HttpSession session = request.getSession(false);
        if(session != null) {
            // 老 Session 作废
            session.invalidate();
        }
        // 获取一个新 Session，什么时候调了 request.getSession()，什么时候 Session 机制才起作用
        request.getSession(true).setAttribute("user", info);
    }

    @GetMapping("/logout")
    public void logout(HttpServletRequest request) throws IOException {
        request.getSession().invalidate();
    }

    @PostMapping
    public UserInfo create(@RequestBody @Validated UserInfo userInfo) throws IOException {
        return userService.create(userInfo);
    }

    @PutMapping("/{id}")
    public UserInfo update(@RequestBody UserInfo user) {
        return null;
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable Long id) {

    }

    /**
     * 想要获取的用户信息，必须和 Authorization 中的用户信息是同一个用户；
     * @param id 用这次请求想要获取的用户的 Id；
     * @param request request.Session 中存放的用户信息，是请求头 Authorization 中携带的，在之前的 Filter 中解析出来存放进 Session 的；
     * @return
     * @throws IOException
     */
    @GetMapping("/{id}")
    public UserInfo get(@PathVariable Long id, HttpServletRequest request) throws IOException {

        // 这里调用了 request.getSession()，就会使 Session 机制生效
        UserInfo user = (UserInfo) request.getSession().getAttribute("user");

        if(user == null || !user.getId().equals(id)) {
            throw new RuntimeException("身份认证信息异常，获取用户信息失败");
        }

        return userService.get(id);
    }

    @GetMapping
    public List<UserInfo> query(String name) {
        return userService.query(name);
    }

}
